//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================

#ifndef __ELASTOS_MUTEX_H__
#define __ELASTOS_MUTEX_H__

class Thread;

class DzMutex : public SyncObject, public UndoOperation
{
public:
    bool_t IsLocked() const
    {
        return (NULL != m_pOwner);
    }

    bool_t IsHeld() const;

    bool_t IsHeldOnce() const;

    void UninterruptibleLock();
    void Lock(WaitResult *pResult);

    void TryUninterruptibleLock(uint_t uTicks, WaitResult *pResult);
    void TryLock(uint_t uTicks, WaitResult *pResult);

    Thread *GetOwner()
    {
        return m_pOwner;
    }

    DLinkNode *GetWaitListHead()
    {
        return &m_waitListHead;
    }

    void Unlock();

    void UnlockBegin();
    void UnlockEnd();

    virtual void Undo(Thread *pThread);

public:
    DzMutex();
    virtual ~DzMutex();

private:
    void AddMutexUndoOperation();
    void RemoveMutexUndoOperation();

private:
    uint_t      m_uNested;

    Thread      *m_pUndoOperationOwner;
    bool_t      m_bUndoOwner;
};

#endif //__ELASTOS_MUTEX_H__
